/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h> 
#include "start_task.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
typedef StaticTask_t osStaticThreadDef_t;
typedef StaticQueue_t osStaticMessageQDef_t;
typedef StaticTimer_t osStaticTimerDef_t;
typedef StaticEventGroup_t osStaticEventGroupDef_t;
/* USER CODE BEGIN PTD */
extern volatile uint32_t ulHighFrequencyTimerTicks;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityRealtime7,
};
/* Definitions for Control_Task */
osThreadId_t Control_TaskHandle;
uint32_t Control_TaskBuffer[ 1024 ];
osStaticThreadDef_t Control_TaskControlBlock;
const osThreadAttr_t Control_Task_attributes = {
  .name = "Control_Task",
  .cb_mem = &Control_TaskControlBlock,
  .cb_size = sizeof(Control_TaskControlBlock),
  .stack_mem = &Control_TaskBuffer[0],
  .stack_size = sizeof(Control_TaskBuffer),
  .priority = (osPriority_t) osPriorityNormal1,
};
/* Definitions for Debug_Task */
osThreadId_t Debug_TaskHandle;
uint32_t Debug_TaskBuffer[ 512 ];
osStaticThreadDef_t Debug_TaskControlBlock;
const osThreadAttr_t Debug_Task_attributes = {
  .name = "Debug_Task",
  .cb_mem = &Debug_TaskControlBlock,
  .cb_size = sizeof(Debug_TaskControlBlock),
  .stack_mem = &Debug_TaskBuffer[0],
  .stack_size = sizeof(Debug_TaskBuffer),
  .priority = (osPriority_t) osPriorityBelowNormal7,
};
/* Definitions for Safe_Task */
osThreadId_t Safe_TaskHandle;
uint32_t Safe_TaskBuffer[ 128 ];
osStaticThreadDef_t Safe_TaskControlBlock;
const osThreadAttr_t Safe_Task_attributes = {
  .name = "Safe_Task",
  .cb_mem = &Safe_TaskControlBlock,
  .cb_size = sizeof(Safe_TaskControlBlock),
  .stack_mem = &Safe_TaskBuffer[0],
  .stack_size = sizeof(Safe_TaskBuffer),
  .priority = (osPriority_t) osPriorityAboveNormal,
};
/* Definitions for CAN_Recv_Task */
osThreadId_t CAN_Recv_TaskHandle;
uint32_t CAN_Recv_TaskBuffer[ 256 ];
osStaticThreadDef_t CAN_Recv_TaskControlBlock;
const osThreadAttr_t CAN_Recv_Task_attributes = {
  .name = "CAN_Recv_Task",
  .cb_mem = &CAN_Recv_TaskControlBlock,
  .cb_size = sizeof(CAN_Recv_TaskControlBlock),
  .stack_mem = &CAN_Recv_TaskBuffer[0],
  .stack_size = sizeof(CAN_Recv_TaskBuffer),
  .priority = (osPriority_t) osPriorityLow5,
};
/* Definitions for IMU_Task */
osThreadId_t IMU_TaskHandle;
uint32_t IMU_TaskBuffer[ 512 ];
osStaticThreadDef_t IMU_TaskControlBlock;
const osThreadAttr_t IMU_Task_attributes = {
  .name = "IMU_Task",
  .cb_mem = &IMU_TaskControlBlock,
  .cb_size = sizeof(IMU_TaskControlBlock),
  .stack_mem = &IMU_TaskBuffer[0],
  .stack_size = sizeof(IMU_TaskBuffer),
  .priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for CAN_Motor_TX_Task */
osThreadId_t CAN_Motor_TX_TaskHandle;
uint32_t CAN_Motor_TX_TaskBuffer[ 128 ];
osStaticThreadDef_t CAN_Motor_TX_TaskControlBlock;
const osThreadAttr_t CAN_Motor_TX_Task_attributes = {
  .name = "CAN_Motor_TX_Task",
  .cb_mem = &CAN_Motor_TX_TaskControlBlock,
  .cb_size = sizeof(CAN_Motor_TX_TaskControlBlock),
  .stack_mem = &CAN_Motor_TX_TaskBuffer[0],
  .stack_size = sizeof(CAN_Motor_TX_TaskBuffer),
  .priority = (osPriority_t) osPriorityNormal3,
};
/* Definitions for CAN_Heartbeat_Check_Task */
osThreadId_t CAN_Heartbeat_Check_TaskHandle;
uint32_t CAN_Heartbeat_Check_TaskBuffer[ 128 ];
osStaticThreadDef_t CAN_Heartbeat_Check_TaskControlBlock;
const osThreadAttr_t CAN_Heartbeat_Check_Task_attributes = {
  .name = "CAN_Heartbeat_Check_Task",
  .cb_mem = &CAN_Heartbeat_Check_TaskControlBlock,
  .cb_size = sizeof(CAN_Heartbeat_Check_TaskControlBlock),
  .stack_mem = &CAN_Heartbeat_Check_TaskBuffer[0],
  .stack_size = sizeof(CAN_Heartbeat_Check_TaskBuffer),
  .priority = (osPriority_t) osPriorityLow4,
};
/* Definitions for CAN_RX_Queue */
osMessageQueueId_t CAN_RX_QueueHandle;
uint8_t CAN_RX_QueueBuffer[ 128 * sizeof( void * ) ];
osStaticMessageQDef_t CAN_RX_QueueControlBlock;
const osMessageQueueAttr_t CAN_RX_Queue_attributes = {
  .name = "CAN_RX_Queue",
  .cb_mem = &CAN_RX_QueueControlBlock,
  .cb_size = sizeof(CAN_RX_QueueControlBlock),
  .mq_mem = &CAN_RX_QueueBuffer,
  .mq_size = sizeof(CAN_RX_QueueBuffer)
};
/* Definitions for CAN_Heartbeat_Check_Timer */
osTimerId_t CAN_Heartbeat_Check_TimerHandle;
osStaticTimerDef_t CAN_Heartbeat_Check_TimerControlBlock;
const osTimerAttr_t CAN_Heartbeat_Check_Timer_attributes = {
  .name = "CAN_Heartbeat_Check_Timer",
  .cb_mem = &CAN_Heartbeat_Check_TimerControlBlock,
  .cb_size = sizeof(CAN_Heartbeat_Check_TimerControlBlock),
};
/* Definitions for VCU_Heartbeat_Check_Timer */
osTimerId_t VCU_Heartbeat_Check_TimerHandle;
osStaticTimerDef_t VCU_Heartbeat_Check_TimerControlBlock;
const osTimerAttr_t VCU_Heartbeat_Check_Timer_attributes = {
  .name = "VCU_Heartbeat_Check_Timer",
  .cb_mem = &VCU_Heartbeat_Check_TimerControlBlock,
  .cb_size = sizeof(VCU_Heartbeat_Check_TimerControlBlock),
};
/* Definitions for myMutex01 */
osMutexId_t myMutex01Handle;
const osMutexAttr_t myMutex01_attributes = {
  .name = "myMutex01"
};
/* Definitions for Safe_Event */
osEventFlagsId_t Safe_EventHandle;
osStaticEventGroupDef_t Safe_EventControlBlock;
const osEventFlagsAttr_t Safe_Event_attributes = {
  .name = "Safe_Event",
  .cb_mem = &Safe_EventControlBlock,
  .cb_size = sizeof(Safe_EventControlBlock),
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);
void Control_APP(void *argument);
void Debug_APP(void *argument);
void Safe_APP(void *argument);
void CAN_Recv_APP(void *argument);
void IMU_APP(void *argument);
void CAN_Motor_TX_APP(void *argument);
void CAN_Heartbeat_Check_APP(void *argument);
void CAN_Heartbeat_Check_Callback(void *argument);
void VCU_Heartbeat_Check_Callback(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* Hook prototypes */
void configureTimerForRunTimeStats(void);
unsigned long getRunTimeCounterValue(void);

/* USER CODE BEGIN 1 */
// extern uint32_t g_osRuntimeCounter;

/* Functions needed when configGENERATE_RUN_TIME_STATS is on */
__weak void configureTimerForRunTimeStats(void)
{
 ulHighFrequencyTimerTicks=0;
}

__weak unsigned long getRunTimeCounterValue(void)
{
return ulHighFrequencyTimerTicks;
}
/* USER CODE END 1 */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */
  /* Create the mutex(es) */
  /* creation of myMutex01 */
  myMutex01Handle = osMutexNew(&myMutex01_attributes);

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* Create the timer(s) */
  /* creation of CAN_Heartbeat_Check_Timer */
  CAN_Heartbeat_Check_TimerHandle = osTimerNew(CAN_Heartbeat_Check_Callback, osTimerPeriodic, NULL, &CAN_Heartbeat_Check_Timer_attributes);

  /* creation of VCU_Heartbeat_Check_Timer */
  VCU_Heartbeat_Check_TimerHandle = osTimerNew(VCU_Heartbeat_Check_Callback, osTimerPeriodic, NULL, &VCU_Heartbeat_Check_Timer_attributes);

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* Create the queue(s) */
  /* creation of CAN_RX_Queue */
  CAN_RX_QueueHandle = osMessageQueueNew (128, sizeof(void *), &CAN_RX_Queue_attributes);

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* creation of Control_Task */
  Control_TaskHandle = osThreadNew(Control_APP, NULL, &Control_Task_attributes);

  /* creation of Debug_Task */
  Debug_TaskHandle = osThreadNew(Debug_APP, NULL, &Debug_Task_attributes);

  /* creation of Safe_Task */
  Safe_TaskHandle = osThreadNew(Safe_APP, NULL, &Safe_Task_attributes);

  /* creation of CAN_Recv_Task */
  CAN_Recv_TaskHandle = osThreadNew(CAN_Recv_APP, NULL, &CAN_Recv_Task_attributes);

  /* creation of IMU_Task */
  IMU_TaskHandle = osThreadNew(IMU_APP, NULL, &IMU_Task_attributes);

  /* creation of CAN_Motor_TX_Task */
  CAN_Motor_TX_TaskHandle = osThreadNew(CAN_Motor_TX_APP, NULL, &CAN_Motor_TX_Task_attributes);

  /* creation of CAN_Heartbeat_Check_Task */
  CAN_Heartbeat_Check_TaskHandle = osThreadNew(CAN_Heartbeat_Check_APP, NULL, &CAN_Heartbeat_Check_Task_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* creation of Safe_Event */
  Safe_EventHandle = osEventFlagsNew(&Safe_Event_attributes);

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  
  //����������ӡ��Ϣ
  LOG_INFO(0,"Start Success!\r\n");
  
  //ADC��ʼ��
//  HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
//	HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_val,1);	// ��ȡADC������ֵ

  
  //��ʼ��������ʾ
  
  start_task();

  /* Infinite loop */
  for(;;)
  {
//    LCD_ShowString(80, 0,(uint8_t *)"STARHARBOUR", BRRED, BLACK, 24, 0);
//		//LCD_ShowChinese(84, 100, (uint8_t *)"����Ƽ�", WHITE, BLACK, 32, 0);
////		LCD_DrawLine(10, 0, 10,  280,WHITE);
////		LCD_DrawLine(270,0, 270, 280,WHITE);
//		LCD_ShowIntNum(50, 170, adc_val[0], 5, WHITE, BLACK, 32);
    //osDelay(1);
    
    osThreadTerminate(defaultTaskHandle);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_Control_APP */
/**
* @brief Function implementing the Control_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Control_APP */
__weak void Control_APP(void *argument)
{
  /* USER CODE BEGIN Control_APP */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END Control_APP */
}

/* USER CODE BEGIN Header_Debug_APP */
/**
* @brief Function implementing the Debug_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Debug_APP */
__weak void Debug_APP(void *argument)
{
  /* USER CODE BEGIN Debug_APP */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END Debug_APP */
}

/* USER CODE BEGIN Header_Safe_APP */
/**
* @brief Function implementing the Safe_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Safe_APP */
__weak void Safe_APP(void *argument)
{
  /* USER CODE BEGIN Safe_APP */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END Safe_APP */
}

/* USER CODE BEGIN Header_CAN_Recv_APP */
/**
* @brief Function implementing the CAN_Recv_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_CAN_Recv_APP */
__weak void CAN_Recv_APP(void *argument)
{
  /* USER CODE BEGIN CAN_Recv_APP */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END CAN_Recv_APP */
}

/* USER CODE BEGIN Header_IMU_APP */
/**
* @brief Function implementing the IMU_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_IMU_APP */
__weak void IMU_APP(void *argument)
{
  /* USER CODE BEGIN IMU_APP */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END IMU_APP */
}

/* USER CODE BEGIN Header_CAN_Motor_TX_APP */
/**
* @brief Function implementing the CAN_Motor_TX_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_CAN_Motor_TX_APP */
__weak void CAN_Motor_TX_APP(void *argument)
{
  /* USER CODE BEGIN CAN_Motor_TX_APP */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END CAN_Motor_TX_APP */
}

/* USER CODE BEGIN Header_CAN_Heartbeat_Check_APP */
/**
* @brief Function implementing the CAN_Heartbeat_Check_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_CAN_Heartbeat_Check_APP */
__weak void CAN_Heartbeat_Check_APP(void *argument)
{
  /* USER CODE BEGIN CAN_Heartbeat_Check_APP */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END CAN_Heartbeat_Check_APP */
}

/* CAN_Heartbeat_Check_Callback function */
__weak void CAN_Heartbeat_Check_Callback(void *argument)
{
  /* USER CODE BEGIN CAN_Heartbeat_Check_Callback */

  /* USER CODE END CAN_Heartbeat_Check_Callback */
}

/* VCU_Heartbeat_Check_Callback function */
__weak void VCU_Heartbeat_Check_Callback(void *argument)
{
  /* USER CODE BEGIN VCU_Heartbeat_Check_Callback */

  /* USER CODE END VCU_Heartbeat_Check_Callback */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

